import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters, getButtons } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink'
import cache from '@/plugins/cache'
import XEUtils from 'xe-utils'

import { setStorage, getStorage } from '@/utils/storage'
// 匹配views里面所有的.vue文件
const modules = import.meta.glob('@/views/**/*.vue')
const routerConfigFields = import.meta.globEager('@/router/config/*.js')
const routerConfig = []
for (const [key, config] of Object.entries(routerConfigFields)) {
  routerConfig.push(config.default)
}
console.log(routerConfig);
const usePermissionStore = defineStore(
  'permission',
  {
    state: () => ({
      isMain: true,
      menuList: null,
      currentModule: 'main',
      currentPage: '/index',
      routes: [],
      addRoutes: [],
      sidebarRouters: [],
      subRoutes: {},
      menuOptions:[]
    }),
    actions: {
      setIsMain(isMain) {
        this.isMain = isMain
      },
      /**
    * @description 设置当前选中的路由及左侧按钮数据
    * @param value 菜单数据中的name字段
    */
      setCurrentModule(value, only) {
        this.currentModule = value
        cache.session.set('currentModule', value)
        if (!this.menuList || only) return
        if (value === 'main') {
          this.setSidebarRouters([{ path: '/index', meta: { title: '首页', icon: 'dingdan_home_selected' } }])
        }
        for (const item of this.menuList) {
          if (item.moduleName === value && item.menuList && item.menuList.length > 0) {
            this.routes = item.menuList
            this.setAllRouters(this.menuList)
            break
          }
        }
      },
      /**
       * @description 设置当前左侧导航选中的菜单
       * @param value 菜单数据中的path字段
       */
      setSubRoutes(value) {
        this.subRoutes = value
      },
      setCurrentPage(value) {
        this.currentPage = value
        cache.session.set('currentPage', value)
      },
      setRoutes(routes) {
        this.addRoutes = routes
        this.routes = constantRoutes.concat(routes)
      },
      setSidebarRouters(routes = constantRoutes) {
        this.sidebarRouters = routes
      },
      setAllRouters(res) {
        setTimeout(() => {
          const currentModule = cache.session.get('currentModule') || 'main'
          const data = (res.find(d => d.moduleName === currentModule))?.menuList
          if (!data) return
          const sdata = JSON.parse(JSON.stringify(data))
          const sidebarRoutes = filterAsyncRouter(sdata)
          // const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
          // asyncRoutes.forEach(route => { router.addRoute(route) })
          this.setSidebarRouters(sidebarRoutes)
        }, 20);
      },
      async generateRoutes(roles) {
        // 向后端请求路由数据
        // const res = await getRouters()
        const res = await getMenu()
        // const buttons = await getButtons()
        const buttons = await getButtonsList()
        window.BTN_AUTH = buttons.data
        this.menuOptions = res?.data||[]
        let data = XEUtils.orderBy(getRouteTree(res?.data || []), 'order')
        data = data.sort(getompare('sort'))
        this.menuList = data
        this.setAllRouters(data)
        const rdata = JSON.parse(JSON.stringify(data.reduce((acc, cur) => acc.concat(cur.menuList), [])))
        const rewriteRoutes = filterAsyncRouter(rdata, false, true)
        this.setRoutes(rewriteRoutes)
        return rewriteRoutes
      }
    }
  })
// 获取菜单
function getMenu (prop) {
  return new Promise(async(resolve, reject) => {
    let res = await getRouters().catch(()=>{})
    if(res?.data?.length){
      setStorage('menuData',res?.data,99999)
    }else{
      res = { data: [] }
      res.data = getStorage('menuData') || []
    }
    resolve(res)
  })
}
// 获取按钮
function getButtonsList (prop) {
  return new Promise(async(resolve, reject) => {
    let res = await getButtons().catch(()=>{})
    if(res?.data?.length){
      setStorage('buttons',res?.data,99999)
    }else{
      res = { data: [] }
      res.data = (getStorage('buttons')) || []
    }
    resolve(res)
  })
}
// 菜单排序
function getompare (prop) {
  return function (obj1, obj2) {
    var val1 = obj1[prop];
    var val2 = obj2[prop];if (val1 < val2) {
        return -1;
    } else if (val1 > val2) {
        return 1;
    } else {
        return 0;
    }            
  } 
}
// 转化菜单树
function getRouteTree(data=[]) {
  const routes = []
  data.forEach(da => {
    const { url: path, sub, name, sort } = da
    const moduleName = path.replace('/', '')
    const module = routerConfig.find(d => d.moduleName === moduleName)
    if (!module) return
    if (name) module.title = name
    const flatRouteList = flatRoutes(module.menuList, '/' + moduleName, true)
    routes.push({ ...module, ...{ menuList: allotMenus(sub, flatRouteList) }, sort })
  })
  return routes
}
// 组装菜单
function allotMenus(routes, flatedRoutes) {
  return routes.reduce((acc, cur) => {
    const { name: title, url: path, sub, icon,alias_name } = cur
    let obj = flatedRoutes.find(d => d.fullPath === path)
    if (!obj) return acc
    if (!obj.meta) obj.meta = {}
    title && (obj.meta.title = title)
    obj.meta.icon = icon || ''
    obj.meta.alias_name = alias_name || ''
    obj.meta.moduleName = obj.fullPath.split('/')[1]
    obj.name = upperName(obj.fullPath).replace(':id', '')
    if (sub?.length) {
      const children = allotMenus(sub, flatedRoutes)
      const child = Object.assign({}, obj, { path: obj.path }, { children })
      return children.length ? acc.concat([child]) : acc
    } else {
      // console.log(10086);
      // console.log(obj);
      if(obj.alwaysShow == true){
        obj.children = []
      }
      // obj.children = []
      return acc.concat([obj])
    }
  }, [])
}
const upperName = name => name.split('/').map(da => da.replace(/^\w/g, d => d.toUpperCase())).join('')

function flatRoutes(routes, pid = '', first) {
  return routes.flatMap(v => {
    const { path } = v
    const fullPath = pid ? `${pid}/${path}` : path
    let re = [{ ...v, ...{ path: first ? fullPath : path, component: path, fullPath } }]
    if (Array.isArray(v.children) && v.children.length) {
      re = re.concat(flatRoutes(v.children, fullPath))
    }
    return re
  })
}

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {


  return asyncRouterMap.filter(route => {
    if (type && route.children) {
      route.children = filterChildren(route.children)
    }
    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout
      } else if (route.component === 'ParentView') {
        route.component = ParentView
      } else if (route.component === 'InnerLink') {
        route.component = InnerLink
      } else {
        route.component = loadView(route)
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type)
    } else {
      delete route['children']
      delete route['redirect']
    }
    return true
  })
}

function filterChildren(childrenMap, lastRouter = false) {
  var children = []
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (el.component === 'ParentView' && !lastRouter) {
        el.children.forEach(c => {
          c.path = el.path + '/' + c.path
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c))
            return
          }
          children.push(c)
        })
        return
      }
    }
    if (lastRouter) {
      el.path = lastRouter.path + '/' + el.path
    }
    children = children.concat(el)
  })
  return children
}

// 动态路由遍历，验证是否具备权限
export function filterDynamicRoutes(routes) {
  const res = []
  routes.forEach(route => {
    if (route.permissions) {
      if (auth.hasPermiOr(route.permissions)) {
        res.push(route)
      }
    } else if (route.roles) {
      if (auth.hasRoleOr(route.roles)) {
        res.push(route)
      }
    }
  })
  return res
}

export const loadView = (route) => {
  let res;
  const { moduleName } = route.meta
  if (moduleName === 'main') {
    for (const path in modules) {
      const dir = path.split('views/')[1].split('.vue')[0];
      if (dir === route.component) {
        res = () => modules[path]();
      }
    }
  } else {
    res = Layout
  }
  return res;
}

export default usePermissionStore
